﻿using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;

namespace Mars.Pathfinding
{
    [BurstCompile]
    public struct FlowFieldCalculationJob : IJobParallelFor
    {
        public int GridWidth;
        public int GridHeight;
        public int2 Destination;
        
        [ReadOnly] public Native2DArray<float> IntegrationField;
        [ReadOnly] public Native2DArray<bool> StaticObstacleGrid;
        [ReadOnly] public Native2DArray<bool> DynamicObstacleGrid;
        [WriteOnly] public Native2DArray<float2> FlowField;
        
        public void Execute(int index)
        {
            int x = index % GridWidth;
            int y = index / GridWidth;

            // 跳过障碍物（静态或动态）和目标点
            bool isObstacle = StaticObstacleGrid[x,y] || DynamicObstacleGrid[x,y];
            if (isObstacle || (x == Destination.x && y == Destination.y))
            {
                FlowField[x,y] = float2.zero;
                return;
            }

            float minCost = float.MaxValue;
            var bestDirection = float2.zero;
            bool foundValidDirection = false;

            // 检查所有邻居
            for (int dx = -1; dx <= 1; dx++)
            {
                for (int dy = -1; dy <= 1; dy++)
                {
                    if (dx == 0 && dy == 0) continue;

                    int nx = x + dx;
                    int ny = y + dy;

                    if (nx < 0 || nx >= GridWidth || ny < 0 || ny >= GridHeight)
                    {
                        continue;
                    }
                    
                    // 跳过障碍物（静态或动态）
                    if (StaticObstacleGrid[nx, ny] || DynamicObstacleGrid[nx, ny])
                    {
                        continue;
                    }

                    float neighborCost = IntegrationField[nx, ny];

                    if (neighborCost >= float.MaxValue)
                    {
                        continue;
                    }

                    if (neighborCost < minCost)
                    {
                        minCost = neighborCost;
                        bestDirection = math.normalize(new float2(dx, dy));
                        foundValidDirection = true;
                    }
                }
            }

            FlowField[x,y] = foundValidDirection ? bestDirection : Vector2.zero;
        }
    }
}